{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_checkpoint:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Checkpoints"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sometimes, it might be useful to store some checkpoints while executing an algorithm. In particular, if a run is very time-consuming. \n",
    "**pymoo** offers to resume a run by serializing the algorithm object and loading it. Resuming runs from checkpoints is possible \n",
    "\n",
    "- the functional way by calling the `minimize` method, \n",
    "- the object-oriented way by repeatedly calling the `next()` method or \n",
    "- from a text file ([Biased Initialization](../customization/initialization.ipynb) from `Population` )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functional"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import dill\n",
    "from pymoo.problems import get_problem\n",
    "\n",
    "from pymoo.algorithms.moo.nsga2 import NSGA2\n",
    "from pymoo.optimize import minimize\n",
    "from pymoo.termination.max_gen import MaximumGenerationTermination\n",
    "\n",
    "problem = get_problem(\"zdt1\", n_var=5)\n",
    "\n",
    "algorithm = NSGA2(pop_size=100)\n",
    "\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 5),\n",
    "               seed=1,\n",
    "               copy_algorithm=False,\n",
    "               verbose=True)\n",
    "\n",
    "with open(\"checkpoint\", \"wb\") as f:\n",
    "    dill.dump(algorithm, f)\n",
    "\n",
    "with open(\"checkpoint\", 'rb') as f:\n",
    "    checkpoint = dill.load(f)\n",
    "    print(\"Loaded Checkpoint:\", checkpoint)\n",
    "\n",
    "# only necessary if for the checkpoint the termination criterion has been met\n",
    "checkpoint.termination = MaximumGenerationTermination(20)\n",
    "\n",
    "res = minimize(problem,\n",
    "               checkpoint,\n",
    "               seed=1,\n",
    "               copy_algorithm=False,\n",
    "               verbose=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Object Oriented"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import dill\n",
    "\n",
    "from pymoo.algorithms.moo.nsga2 import NSGA2\n",
    "from pymoo.problems import get_problem\n",
    "\n",
    "problem = get_problem(\"zdt1\", n_var=5)\n",
    "\n",
    "algorithm = NSGA2(pop_size=100)\n",
    "\n",
    "algorithm.setup(problem, seed=1, termination=('n_gen', 20))\n",
    "\n",
    "for k in range(5):\n",
    "    algorithm.next()\n",
    "    print(algorithm.n_gen)\n",
    "\n",
    "    with open(\"checkpoint\", \"wb\") as f:\n",
    "        dill.dump(algorithm, f)\n",
    "    \n",
    "    \n",
    "with open(\"checkpoint\", 'rb') as f:\n",
    "    checkpoint = dill.load(f)\n",
    "    print(\"Loaded Checkpoint:\", checkpoint)\n",
    "\n",
    "while checkpoint.has_next():\n",
    "    checkpoint.next()\n",
    "    print(checkpoint.n_gen)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## From a Text File"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, load the data from a file. Usually, this will include the variables `X`, the objective values `F` (and the constraints `G`). Here, they are created randomly. Always make sure the `Problem` you are solving would return the same values for the given `X` values. Otherwise the data might be misleading for the algorithm.\n",
    "\n",
    "(This is not the case here. It is really JUST for illustration purposes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from pymoo.problems.single import G1\n",
    "\n",
    "problem = G1()\n",
    "\n",
    "N = 300\n",
    "np.random.seed(1)\n",
    "X = np.random.random((N, problem.n_var))\n",
    "\n",
    "# here F and G is re-evaluated - in practice you want to load them from files too\n",
    "F, G = problem.evaluate(X, return_values_of=[\"F\", \"G\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, create a population object using your data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from pymoo.core.evaluator import Evaluator\n",
    "from pymoo.core.population import Population\n",
    "from pymoo.problems.static import StaticProblem\n",
    "\n",
    "# now the population object with all its attributes is created (CV, feasible, ...)\n",
    "pop = Population.new(\"X\", X)\n",
    "pop = Evaluator().eval(StaticProblem(problem, F=F, G=G), pop)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And finally run it with a non-random initial population `sampling=pop`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from pymoo.algorithms.soo.nonconvex.ga import GA\n",
    "from pymoo.optimize import minimize\n",
    "\n",
    "# the algorithm is now called with the population - biased initialization\n",
    "algorithm = GA(pop_size=100, sampling=pop)\n",
    "\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 10),\n",
    "               seed=1,\n",
    "               verbose=True)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
